#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/11/14 10:10
# @Author : XXX
# @Site : 
# @File : choose_best_action.py
# @Software: PyCharm
import numpy as np
from scipy.optimize import minimize

from control_temp import pre_cdu_tso_fun
from collections import deque
from util.loguru_util import myLogger
from all_config import dryFan_action_range, cduvalvue_range, need_all_key
#################################工具变量####################################


deque_save_pre_cduTso = deque([8888, 8888], maxlen=2)



# 定义目标函数
def objective_function(x, a, b, c):
    '''

    :param x:动作向量
    :param a:环境状态
    :param b:预控制的温度范围
    :return:
    '''
    x1, x2, x3, x4, x5, c1 = x
    pre_cduTso = pre_cdu_tso_fun(x1, x2, x3, x4, x5, c1, a, b)
    output = abs(pre_cduTso - c)
    return output

# 定义约束函数
def constraint_x1_lower(x, lower_bound):
    return x[0] - lower_bound  # 不等式约束: x1 >= lower_bound

def constraint_x1_upper(x, upper_bound):
    return upper_bound - x[0]  # 不等式约束: x1 <= upper_bound

def constraint_x2_lower(x, lower_bound):
    return x[1] - lower_bound  # 不等式约束: x2 >= lower_bound

def constraint_x2_upper(x, upper_bound):
    return upper_bound - x[1]  # 不等式约束: x2 <= upper_bound
# 定义约束函数
def constraint_x3_lower(x, lower_bound):
    return x[2] - lower_bound  # 不等式约束: x1 >= lower_bound

def constraint_x3_upper(x, upper_bound):
    return upper_bound - x[2]  # 不等式约束: x1 <= upper_bound

def constraint_x4_lower(x, lower_bound):
    return x[3] - lower_bound  # 不等式约束: x2 >= lower_bound

def constraint_x4_upper(x, upper_bound):
    return upper_bound - x[3]  # 不等式约束: x2 <= upper_bound
# 定义约束函数
def constraint_x5_lower(x, lower_bound):
    return x[4] - lower_bound  # 不等式约束: x1 >= lower_bound

def constraint_x5_upper(x, upper_bound):
    return upper_bound - x[4]  # 不等式约束: x1 <= upper_bound

def constraint_c1_lower(x, lower_bound):
    return x[5] - lower_bound  # 不等式约束: x2 >= lower_bound

def constraint_c1_upper(x, upper_bound):
    return upper_bound - x[5]  # 不等式约束: x2 <= upper_bound



# 非变量参数
x1_lower_bound = dryFan_action_range[0][0]
x1_upper_bound = dryFan_action_range[0][1]
x2_lower_bound = dryFan_action_range[1][0]
x2_upper_bound = dryFan_action_range[1][1]
x3_lower_bound = dryFan_action_range[2][0]  # 更正此处
x3_upper_bound = dryFan_action_range[2][1]  # 更正此处
x4_lower_bound = dryFan_action_range[3][0]  # 更正此处
x4_upper_bound = dryFan_action_range[3][1]  # 更正此处
x5_lower_bound = dryFan_action_range[4][0]  # 更正此处
x5_upper_bound = dryFan_action_range[4][1]  # 更正此处
c1_lower_bound = cduvalvue_range[0]
c1_upper_bound = cduvalvue_range[1]

# 初始猜测点
x0 = np.array([10.0, 10.0, 10.0, 10.0, 10.0, 10.0])

# 定义约束
constraints = [
    {'type': 'ineq', 'fun': constraint_x1_lower, 'args': (x1_lower_bound,)},
    {'type': 'ineq', 'fun': constraint_x1_upper, 'args': (x1_upper_bound,)},
    {'type': 'ineq', 'fun': constraint_x2_lower, 'args': (x2_lower_bound,)},
    {'type': 'ineq', 'fun': constraint_x2_upper, 'args': (x2_upper_bound,)},
    {'type': 'ineq', 'fun': constraint_x3_lower, 'args': (x3_lower_bound,)},
    {'type': 'ineq', 'fun': constraint_x3_upper, 'args': (x3_upper_bound,)},
    {'type': 'ineq', 'fun': constraint_x4_lower, 'args': (x4_lower_bound,)},
    {'type': 'ineq', 'fun': constraint_x4_upper, 'args': (x4_upper_bound,)},
    {'type': 'ineq', 'fun': constraint_x5_lower, 'args': (x5_lower_bound,)},
    {'type': 'ineq', 'fun': constraint_x5_upper, 'args': (x5_upper_bound,)},
    {'type': 'ineq', 'fun': constraint_c1_lower, 'args': (c1_lower_bound,)},
    {'type': 'ineq', 'fun': constraint_c1_upper, 'args': (c1_upper_bound,)}
]



def choose_best_action(state_dict = None, need_cdu_tso_int = 40,need_all_key= None):
    '''

    :param dryfan_action_spae_list:风扇的状态空间，
    :param cduvalvue_action_spacelist:cduvalvue的状态空间
    :param state_dict:状态的字典
    :param need_cdu_tso_int:需要控制到的温度
    :return:返回一个列表，第一个为风扇的转速，第二个为cduvalvue
    '''



######################输出环境状态###########################
    new_all_sorted_dict = {}

    for key in need_all_key:
        new_all_sorted_dict[key] = state_dict[key]

    myLogger.info(f"当前环境状态为:{new_all_sorted_dict}")

#####################################优化部分##############################
    # 使用minimize函数进行优化，并通过args传递额外参数
    result = minimize(objective_function, x0, args=(new_all_sorted_dict, need_all_key, need_cdu_tso_int),
                      constraints=constraints, method='COBYLA')
    myLogger.info(f"Optimized parameters:{result.x}")
    myLogger.info(f"Objective function value (COBYLA):{result.fun}")

    action = [int(x) for x in result.x]
    dryfan1 = action[0]
    dryfan2 = action[1]
    dryfan3 = action[2]
    dryfan4 = action[3]
    dryfan5 = action[4]
    cduValve1 = action[5]


    ## 输出测试信息
    deque_save_pre_cduTso.append(pre_cdu_tso_fun(dryfan1, dryfan2,dryfan3,dryfan4,dryfan5,
                                                 cduValve1, state_dict, need_all_key=need_all_key))
    myLogger.info(f"预测的温度为(此处为上一轮的预测结果):{deque_save_pre_cduTso[0]}")
    myLogger.info(f"当前一轮的实际温度为:{new_all_sorted_dict['cduTso']}")

    return [dryfan1, dryfan2, dryfan3, dryfan4, dryfan5, cduValve1]

if __name__ == '__main__':
    env_state_list = [
        {'temperature': 27.9, 'cduTsi': 45.1, 'cduTfi': 29.4, 'cduTfo': 43.2, 'cduValve1': 28.0, 'dryFan1': 75.0,
         'cduTso': 50.0, 'cduFf':50, 'cduFs':50, 'pduPower':55, 'dryFan2':50, 'dryFan3':50, 'dryFan4':50,'dryFan5':50,'pumpPump':50},
        {'temperature': 27.9, 'cduTsi': 47, 'cduTfi': 29.4, 'cduTfo': 43.2, 'cduValve1': 28.0, 'dryFan1': 75.0,
         'cduTso': 38, 'cduFf':50, 'cduFs':50,'pduPower':55, 'dryFan2':50, 'dryFan3':50, 'dryFan4':50,'dryFan5':50, 'pumpPump':50}
    ]

    for state in env_state_list:
        action = choose_best_action(state ,need_all_key=need_all_key)